package com.sayice.robotconflict.game.object.logic;

import cn.hutool.core.util.NumberUtil;
import com.sayice.robotconflict.game.object.Robot;
import com.sayice.robotconflict.game.object.property.Coord;
import com.sayice.robotconflict.game.object.property.SimpleCoord;

import java.util.List;
import java.util.Map;
import java.util.function.BiConsumer;

/**
 * 设置函数
 *
 * @author shubing
 */
public enum SetFunc {
    SET_ATTACK_VALUE((robot, params) -> robot.attackValue = NumberUtil.parseNumber(params[0].toString()).intValue()),
    
    SET_ATTACK_BIAS((robot, params) -> robot.attackBias = NumberUtil.parseNumber(params[0].toString()).intValue()),
    
    SET_MOVE_TARGET((robot, params) -> {
        if (robot.controlled) {
            return;
        }
        Object param = params[0];
        if (param instanceof List<?>) {
            List<?> coord = (List<?>) param;
            robot.moveTargetSupplier = () -> {
                // 客户端传来的坐标可能不是数字，需要处理异常
                try {
                    return new SimpleCoord(
                            NumberUtil.parseNumber(coord.get(0).toString()).doubleValue(),
                            NumberUtil.parseNumber(coord.get(1).toString()).doubleValue()
                    );
                } catch (Exception e) {
                    return null;
                }
            };
        } else if (param instanceof Map<?, ?>) {
            Map<?, ?> funcValue = (Map<?, ?>) param;
            ComplexGetFunc func = ComplexGetFunc.valueOf((String) funcValue.get("func"));
            robot.moveTargetSupplier = () -> {
                try {
                    return (Coord) func.get(robot, (Object[]) null);
                } catch (Exception e) {
                    return null;
                }
            };
        }
    }),
    
    SET_MOVE_TARGET_DISTANCE((robot, params) -> {
        if (robot.controlled) {
            return;
        }
        Object param = params[0];
        if (param instanceof Number) {
            robot.moveTargetDistance = ((Number) param).intValue();
        } else if (param instanceof String) {
            robot.moveTargetDistance = NumberUtil.parseNumber((params[0]).toString()).intValue();
        } else if (param instanceof Map<?, ?>) {
            Map<?, ?> funcValue = (Map<?, ?>) param;
            SimpleGetFunc func = SimpleGetFunc.valueOf((String) funcValue.get("func"));
            robot.moveTargetDistance = func.get(robot, (Object[]) null);
        }
    }),
    
    ATTACK((robot, params) -> {
        if (robot.controlled) {
            return;
        }
        robot.attack();
    });
    
    private BiConsumer<Robot, Object[]> fn;
    
    SetFunc(BiConsumer<Robot, Object[]> fn) {
        this.fn = fn;
    }
    
    public void set(Robot robot, Object... params) {
        fn.accept(robot, params);
    }
}
